package com.kye.express.business.jd_reservation.edit;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;

import com.bigkoo.pickerview.TimePickerView;
import com.jakewharton.rxbinding2.view.RxView;
import com.jakewharton.rxbinding2.view.RxViewGroup;
import com.jakewharton.rxbinding2.view.ViewGroupHierarchyChangeEvent;
import com.jakewharton.rxbinding2.widget.RxTextView;
import com.kye.base.DebounceObservableTransformer;
import com.kye.datetimepicker.DateTimePicker;
import com.kye.express.R;
import com.kye.express.business.base.BaseAppCompatActivity;
import com.kye.express.databinding.ActivityJdReservationEditBinding;
import com.kye.express.utils.ToolbarManager;
import com.kye.express.view.KyeProgressDialog;
import com.kye.express.view.ToastManager;
import com.kye.express.view.reclyerview.OnItemClickListener;
import com.kye.model.bean.jd_reservation.JDReservationBean;
import com.kye.model.bean.jd_reservation.JDWaybillsBean;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function5;
import io.reactivex.functions.Predicate;
import me.drakeet.multitype.MultiTypeAdapter;

public class JdReservationEditActivity extends BaseAppCompatActivity implements JdReservationEditContract.JdReservationEditView {
    private static final String PURCHASE_ITEM_HINT = "请输入采购单号";
    private static final String APPOINT_ITEM_HINT = "请输入预约单号";

    private static final String KEY_JD_WAYBILL = "KEY_JD_WAYBILL";
    private static final String KEY_JD_RESERVATION = "KEY_JDRESERVATION";

    private static final int REQUEST_CODE_JD_WAYBILL = 1;

    private ActivityJdReservationEditBinding mBinding;
    private MultiTypeAdapter mPurchaseAdapter;
    private MultiTypeAdapter mAppointAdapter;
    private ItemEditViewBinder mPurchaseItemEditViewBinder;
    private ItemEditViewBinder mAppointItemEditViewBinder;

    private TimePickerView mStartTimePickerView;
    private TimePickerView mEndTimePickerView;
    private JdReservationEditContract.JdReservationEditPresenter mPresenter;
    private Dialog mDialog;
    private JDReservationBean.JDReservation mJdReservation;

    public static void startActivityForResult(Activity activity, int requestCode) {
        activity.startActivityForResult(
                new Intent(activity, JdReservationEditActivity.class),
                requestCode
        );
    }

    public static void startActivityForResult(Activity activity, JDReservationBean.JDReservation item, int requestCode) {
        activity.startActivityForResult(
                new Intent(activity, JdReservationEditActivity.class)
                        .putExtra(KEY_JD_RESERVATION, item),
                requestCode
        );
    }

    public static void startActivityForResult(Activity activity, JDWaybillsBean.JDWaybill jdWaybill, int requestCode) {
        activity.startActivityForResult(
                new Intent(activity, JdReservationEditActivity.class)
                        .putExtra(KEY_JD_WAYBILL, jdWaybill),
                requestCode
        );
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_jd_reservation_edit);

        initView();
        initEvent();
        initData();
    }

    private void initView() {
        mBinding.recyclerViewPurchaseCode.setLayoutManager(new LinearLayoutManager(this) {
            @Override
            public boolean canScrollVertically() {
                return false;
            }
        });

        mPurchaseAdapter = new MultiTypeAdapter(Arrays.asList(new ItemEdit(PURCHASE_ITEM_HINT)));
        mPurchaseItemEditViewBinder = new ItemEditViewBinder();
        mPurchaseAdapter.register(ItemEdit.class, mPurchaseItemEditViewBinder);
        mBinding.recyclerViewPurchaseCode.setAdapter(mPurchaseAdapter);

        mBinding.recyclerViewAppointCode.setLayoutManager(new LinearLayoutManager(this) {
            @Override
            public boolean canScrollVertically() {
                return false;
            }
        });

        mAppointAdapter = new MultiTypeAdapter(Arrays.asList(new ItemEdit(APPOINT_ITEM_HINT)));
        mAppointItemEditViewBinder = new ItemEditViewBinder();
        mAppointAdapter.register(ItemEdit.class, mAppointItemEditViewBinder);
        mBinding.recyclerViewAppointCode.setAdapter(mAppointAdapter);
    }

    private void initEvent() {
        ToolbarManager.setToolbar(this, mBinding.toolbar);

        RxView.clicks(mBinding.imageButtonAddWaybill)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        JdWaybillListActivity.startActivityForResult(JdReservationEditActivity.this, REQUEST_CODE_JD_WAYBILL);
                    }
                });

        RxView.clicks(mBinding.linearLayoutStartTime)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        mStartTimePickerView = DateTimePicker.show(JdReservationEditActivity.this, true, true, true, true, true, false, Calendar.getInstance(), null, new DateTimePicker.DateTimeCallBack() {
                            @Override
                            public void callBack(Date date) {
                                if (date.getTime() < System.currentTimeMillis()) {
                                    ToastManager.show(getApplicationContext(), "开始时间不能早于现在");
                                    return;
                                }

                                if (mBinding.getEndTime() != null && date.getTime() > mBinding.getEndTime().getTime()) {
                                    ToastManager.show(getApplicationContext(), "开始时间不能晚于结束时间");
                                    return;
                                }

                                if (date.getTime() - System.currentTimeMillis() < 6 * 1000 * 60 * 60) {
                                    ToastManager.show(getApplicationContext(), "预约开始时间必须大于当前时间6个小时,否则联系对应市场员加急处理");
                                }
                                mBinding.setStartTime(date);
                            }
                        });
                    }
                });

        RxView.clicks(mBinding.linearLayoutEndTime)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        Calendar calendar = Calendar.getInstance();
                        if (mBinding.getStartTime() != null) calendar.setTime(mBinding.getStartTime());

                        mEndTimePickerView = DateTimePicker.show(JdReservationEditActivity.this, true, true, true, true, true, false, calendar, null, new DateTimePicker.DateTimeCallBack() {
                            @Override
                            public void callBack(Date date) {
                                if (date.getTime() < System.currentTimeMillis()) {
                                    ToastManager.show(getApplicationContext(), "结束时间不能早于现在");
                                    return;
                                }

                                if (mBinding.getStartTime() != null &&date.getTime() < mBinding.getStartTime().getTime()) {
                                    ToastManager.show(getApplicationContext(), "结束时间不能早于开始时间");
                                    return;
                                }
                                mBinding.setEndTime(date);
                            }
                        });
                    }
                });

        mPurchaseItemEditViewBinder.setLastTextWatcher(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                final ArrayList<Object> objects = new ArrayList<>();
                objects.addAll(mPurchaseAdapter.getItems());
                objects.add(new ItemEdit(PURCHASE_ITEM_HINT));
                mPurchaseAdapter.setItems(objects);

                mPurchaseAdapter.notifyItemChanged(objects.size() - 2, true);
                mPurchaseAdapter.notifyItemInserted(objects.size() - 1);
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        mPurchaseItemEditViewBinder.setOnItemDeleteClickListener(new OnItemClickListener<Integer>() {
            @Override
            public void onClickItem(Integer position, View view) {
                final List<?> items = mPurchaseAdapter.getItems();
                items.remove(position.intValue());
                mPurchaseAdapter.setItems(items);

                mPurchaseAdapter.notifyItemRemoved(position);
            }
        });


        mAppointItemEditViewBinder.setLastTextWatcher(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                final ArrayList<Object> objects = new ArrayList<>();
                objects.addAll(mAppointAdapter.getItems());
                objects.add(new ItemEdit(APPOINT_ITEM_HINT));
                mAppointAdapter.setItems(objects);

                mAppointAdapter.notifyItemChanged(objects.size() - 2, "占位判断, 其实传什么都可以");
                mAppointAdapter.notifyItemInserted(objects.size() - 1);
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        mAppointItemEditViewBinder.setOnItemDeleteClickListener(new OnItemClickListener<Integer>() {
            @Override
            public void onClickItem(Integer position, View view) {
                final List<?> items = mAppointAdapter.getItems();
                items.remove(position.intValue());
                mAppointAdapter.setItems(items);

                mAppointAdapter.notifyItemRemoved(position);
            }
        });

        RxView.focusChanges(mBinding.editTextWaybillCode)
                .compose(bindToLifecycle())
                .filter(new Predicate<Boolean>() {
                    @Override
                    public boolean test(Boolean aBoolean) throws Exception {
                        return mPresenter != null && mBinding.getJdWaybill() == null;
                    }
                })
                .skip(1)
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        if (mPresenter == null) return;
                        mPresenter.getWaybill(mBinding.editTextWaybillCode.getText().toString().trim());
                    }
                });

        Observable.combineLatest(
                RxTextView.textChanges(mBinding.textViewSendCompany),
                RxTextView.textChanges(mBinding.textViewStartTime),
                RxTextView.textChanges(mBinding.textViewEndTime),
                RxViewGroup.changeEvents(mBinding.recyclerViewAppointCode),
                RxViewGroup.changeEvents(mBinding.recyclerViewPurchaseCode),
                new Function5<CharSequence, CharSequence, CharSequence, ViewGroupHierarchyChangeEvent, ViewGroupHierarchyChangeEvent, Boolean>() {
                    @Override
                    public Boolean apply(CharSequence charSequence, CharSequence charSequence2, CharSequence charSequence3, ViewGroupHierarchyChangeEvent viewGroupHierarchyChangeEvent, ViewGroupHierarchyChangeEvent viewGroupHierarchyChangeEvent2) throws Exception {
                        return !TextUtils.isEmpty(charSequence) &&
                                !TextUtils.isEmpty(charSequence2) &&
                                !TextUtils.isEmpty(charSequence3) &&
                                viewGroupHierarchyChangeEvent.view().getChildCount() > 1 &&
                                viewGroupHierarchyChangeEvent2.view().getChildCount() > 1;
                    }
                }
        )
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        mBinding.buttonSubmit.setEnabled(aBoolean);
                    }
                });


        RxView.clicks(mBinding.buttonSubmit)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        mPresenter.submit(
                                mJdReservation != null ? mJdReservation.getBillId() : null,
                                mBinding.editTextWaybillCode.getText().toString().trim(),
                                mBinding.getJdWaybill().getItemCount(),
                                mBinding.editTextAppointCount.getText().toString().trim(),
                                mAppointAdapter.getItems(),
                                mBinding.getStartTime(),
                                mBinding.editTextProductCode.getText().toString().trim(),
                                mPurchaseAdapter.getItems(),
                                mBinding.getEndTime(),
                                mBinding.editTextReservationWarehouse.getText().toString().trim()
                        );
                    }
                });
    }

    private void initData() {
        mPresenter = new JdReservationEditContract.JdReservationEditPresenter();
        mPresenter.bind(this);

        final JDWaybillsBean.JDWaybill jdWaybill = (JDWaybillsBean.JDWaybill) getIntent().getSerializableExtra(KEY_JD_WAYBILL);
        if (jdWaybill != null) {
            mBinding.editTextWaybillCode.setText(jdWaybill.getWaybill());
            mBinding.setJdWaybill(jdWaybill);
        }

        mJdReservation = (JDReservationBean.JDReservation) getIntent().getSerializableExtra(KEY_JD_RESERVATION);
        if (mJdReservation != null) {
            mBinding.editTextWaybillCode.setText(mJdReservation.getOrderno());
            mBinding.setJdWaybill(new JDWaybillsBean.JDWaybill(mJdReservation.getOrderno(), mJdReservation.getSendCompany(), Integer.parseInt(mJdReservation.getTotalCount()), mJdReservation.getPackCompany(), null));

            mBinding.setStartTime(mJdReservation.getApppointSTime());
            mBinding.setEndTime(mJdReservation.getApppointETime());

            mBinding.editTextReservationWarehouse.setText(mJdReservation.getReservationWarehouse());
            mBinding.editTextAppointCount.setText(mJdReservation.getAppointCount());
            mBinding.editTextProductCode.setText(mJdReservation.getGoodsCode());

            {
                final ArrayList<ItemEdit> appointItemEdits = new ArrayList<>();
                final String appointCode = mJdReservation.getAppointCode();
                final String[] split = appointCode.split(",");
                for (String s : split) appointItemEdits.add(new ItemEdit(APPOINT_ITEM_HINT, s));

                appointItemEdits.add(new ItemEdit(APPOINT_ITEM_HINT));

                mAppointAdapter.setItems(appointItemEdits);
                mAppointAdapter.notifyDataSetChanged();
            }

            {
                final ArrayList<ItemEdit> purchaseItemEdits = new ArrayList<>();
                final String appointCode = mJdReservation.getAppointCode();
                final String[] split = appointCode.split(",");
                for (String s : split) purchaseItemEdits.add(new ItemEdit(PURCHASE_ITEM_HINT, s));

                purchaseItemEdits.add(new ItemEdit(PURCHASE_ITEM_HINT));

                mPurchaseAdapter.setItems(purchaseItemEdits);
                mPurchaseAdapter.notifyDataSetChanged();
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (REQUEST_CODE_JD_WAYBILL == requestCode && RESULT_OK == resultCode && data != null) {
            final JDWaybillsBean.JDWaybill jdWaybill = (JDWaybillsBean.JDWaybill) data.getSerializableExtra(JdWaybillListActivity.KEY_JDWAYBILL);
            mBinding.editTextWaybillCode.setText(jdWaybill.getWaybill());
            onGetJdWaybill(jdWaybill);
        }
    }

    @Override
    public void onError() {
        ToastManager.show(this, R.string.common_net_error);
    }

    @Override
    public void onError(String msg) {
        ToastManager.show(this, msg);
    }

    @Override
    public void onLoading() {
        mDialog = KyeProgressDialog.show(this, mDialog);
    }

    @Override
    public void onLoaded() {
        KyeProgressDialog.dismiss(mDialog);
    }

    @Override
    public void onGetJdWaybill(JDWaybillsBean.JDWaybill jDWaybill) {
        mBinding.setJdWaybill(jDWaybill);
    }

    @Override
    public void onAddOrUpdateSuccess() {
        setResult(RESULT_OK);
        finish();
    }
}
